package com.ecarx.vhaltests.hy11.testcases.climate;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.AIR_FRAGRANCE_SLOT_1;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.AIR_FRAGRANCE_SLOT_2;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.AIR_FRAGRANCE_SLOT_3;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.HVAC_FUNC_AIR_FRAGRANCE_LEVEL;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.HVAC_FUNC_AIR_FRAGRANCE_SLOT;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.HVAC_FUNC_AIR_FRAGRANCE_TYPE_ID;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AIR_FRAGRANCE_LEVEL_1;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AIR_FRAGRANCE_LEVEL_2;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AIR_FRAGRANCE_LEVEL_3;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.AIR_FRAGRANCE_LEVEL_OFF;
import static org.junit.Assert.assertEquals;
import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacFuncAirFragranceLevelTest extends VhalUnitTestBase {
    private static IWrapper.IPropertyId propertyId;
    private static IWrapper.IPropertyId setSlot;
    protected static IWrapper wrapper;
    private static IpcpClient ipcpClient = new IpcpClient();
    private static final int AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
    private static int LVL_OFF;
    private static int LVL_1;
    private static int LVL_2;
    private static int LVL_3;
    private static int SLOT_1;
    private static int SLOT_2;
    private static int SLOT_3;

    private static int cbkPropValue;
    private static int cbkPropStatus;

    @BeforeClass
    public static void testInit() {
        wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        propertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_AIR_FRAGRANCE_LEVEL);
        LVL_OFF = propertyId.getPropertyValue(AIR_FRAGRANCE_LEVEL_OFF);
        LVL_1 = propertyId.getPropertyValue(AIR_FRAGRANCE_LEVEL_1);
        LVL_2 = propertyId.getPropertyValue(AIR_FRAGRANCE_LEVEL_2);
        LVL_3 = propertyId.getPropertyValue(AIR_FRAGRANCE_LEVEL_3);
        setSlot = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_AIR_FRAGRANCE_SLOT);
        SLOT_1 = setSlot.getPropertyValue(AIR_FRAGRANCE_SLOT_1);
        SLOT_2 = setSlot.getPropertyValue(AIR_FRAGRANCE_SLOT_2);
        SLOT_3 = setSlot.getPropertyValue(AIR_FRAGRANCE_SLOT_3);
        setConfig();
    }

    public boolean availability(){
        return mCarPropertyMgr.isPropertyAvailable(propertyId.getPropertyId(), AREA_ID);
    }

    public static void setConfig(){
        int ccSvcId = 135;
        int[] ccOperIds = {200};
        boolean ccSet = ipcpClient.setConfig(ccSvcId, ccOperIds);
        assertEquals(true, ccSet);

        int cemSvcId = 37;
        int[] cemOperId = {999};
        boolean cemResult = ipcpClient.setConfig(cemSvcId, cemOperId);
        assertEquals(true, cemResult);
        delay();
    }

    public void setCarConfig(boolean isAvail){
        int ccSvcId = 135;
        int ccOperIds = 200;
        int[] configs = {505};
        int[] values = {isAvail? 2:1};
        boolean ccResult = ipcpClient.setCarconfigSignal(ccSvcId, ccOperIds, configs, values);
        delay();
        assertEquals(true, ccResult);
        Log.d("vli", "setCarConfig pass");
    }

    public void setCem(boolean isActive){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1"};
        int[] cemValues = {isActive? VehicleConstants.USG_MODE_CONVENIENCE:VehicleConstants.USG_MODE_ABANDON,
                VehicleConstants.CAR_MODE_DYNO};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        delay();
        assertEquals(true, cemUsgResult);
        Log.d("vli", "setCem pass");
    }

    public void setUsgModInactive(){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1"};
        int[] cemValues = { VehicleConstants.USG_MODE_INACTIVE, VehicleConstants.CAR_MODE_DYNO};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        delay();
        assertEquals(true, cemUsgResult);
    }

    public void mockTypeIdFrmMcu(int Id1, int Id2, int Id3){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragCh1Id", "fragCh2Id", "fragCh3Id"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, Id1, Id2, Id3};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    public void mockTypeIdAndAirFragChRunningStsAndStsAndLvl(int Id1, int Id2, int Id3, int ch1, int ch2, int ch3,int StsFrmMcu, int LvlFrmMcu){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragCh1Id", "fragCh2Id", "fragCh3Id","airFragCh1RunngSts", "airFragCh2RunngSts", "airFragCh3RunngSts","fragStsFrmClima", "fragLvlFrmClima"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, Id1, Id2, Id3, ch1, ch2, ch3, StsFrmMcu, LvlFrmMcu};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    public void mockAirFragChRunningSts(int ch1, int ch2, int ch3){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","airFragCh1RunngSts", "airFragCh2RunngSts", "airFragCh3RunngSts",};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, ch1, ch2, ch3};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    public int[] getFragTypeId(){
        wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        IWrapper.IPropertyId fragTypeId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_AIR_FRAGRANCE_TYPE_ID);
        return mCarPropertyMgr.getIntArrayProperty(fragTypeId.getPropertyId(), AREA_ID);
    }

    public void selectSlot(int slot){
        if(slot==1){
            mCarPropertyMgr.setIntProperty(setSlot.getPropertyId(), AREA_ID, SLOT_1);
        }else if(slot==2){
            mCarPropertyMgr.setIntProperty(setSlot.getPropertyId(), AREA_ID, SLOT_2);
        }else if(slot==3){
            mCarPropertyMgr.setIntProperty(setSlot.getPropertyId(), AREA_ID, SLOT_3);
        }
    }


    public void mockTypeIdAndFragStsAndFragLvlFrmMcu(int Id1, int Id2, int Id3, int StsFrmMcu, int LvlFrmMcu){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragCh1Id", "fragCh2Id", "fragCh3Id","fragStsFrmClima", "fragLvlFrmClima"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO,Id1, Id2, Id3, StsFrmMcu, LvlFrmMcu};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    public void mockFragStsAndFragLvlFrmMcu(int StsFrmMcu, int LvlFrmMcu){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragStsFrmClima", "fragLvlFrmClima"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, StsFrmMcu, LvlFrmMcu};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    public void mockFragStsFrmMcu(int StsFrmMcu){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragStsFrmClima"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, StsFrmMcu};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    public void mockTypeIdAndFragStsFrmMcu(int Id1, int Id2, int Id3, int StsFrmMcu){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragCh1Id", "fragCh2Id", "fragCh3Id","fragStsFrmClima"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, Id1, Id2, Id3, StsFrmMcu};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    public void mockTypeIdAndFragLvlFrmMcu(int Id1, int Id2, int Id3, int LvlFrmMcu){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragCh1Id", "fragCh2Id", "fragCh3Id", "fragLvlFrmClima"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, Id1, Id2, Id3, LvlFrmMcu};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        assertEquals(true, cemUsgResult);
        delay();
    }

    @Test
    public void test_001AirFragLvlActive(){
        setCarConfig(false);
        setCarConfig(true);
//        setCem(true);
        mockTypeIdFrmMcu(224,225,255);
        delay();
        int propStatus = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(0, propStatus);
        assertEquals(true, availability());
    }

    @Test
    public void test_002AirFragLvlNotActive(){
        setCarConfig(true);
        setCem(false);
        mockTypeIdFrmMcu(0, 0, 0);
        delay();
        int propStatus = mCarPropertyMgr.getProperty(propertyId.getPropertyId(),AREA_ID).getStatus();
        assertEquals(1, propStatus);
        assertEquals(false, availability());
    }

    @Test
    public void test_003AirFraglvlNotAvail(){
        setCarConfig(false);
        delay();
        assertEquals(false, availability());
    }

    @Test
    public void test_005UsgModInactive(){
        setCarConfig(true);
        setCem(true);
        //选择通道1,设置浓度为lvl2
        selectSlot(1);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,1,0,0, 2, 2);
        delay(3000);
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_2);
//        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,1,0,0, 2, 2);
        assertEquals(SLOT_1, mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID));
        assertEquals(LVL_2, mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID));
        //UsgMode变为Inactive,会记忆当前用户设置的香氛浓度等级
        setUsgModInactive();
        //此时香氛浓度切换至NotActive状态
        assertEquals(1, mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus());
        //恢复至active状态检查保存的浓度值是否为lvl2, typeId!=0,sts=off,此时选择通道后会恢复上次保存的浓度
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,1,0,0, 1, 2);
        delay();
        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(LVL_2, res);
    }

    @Test
    public void test_006UsgModFrmInActvToCnvincStsOnLvl(){
        setCarConfig(true);
        setUsgModInactive();
        mockTypeIdFrmMcu(224,225,255);
        setCem(true);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,1);
        //UsgMode从Inactive变为Convenience,如果通道Id不是0
        delay(1000);
        int[] typeId = getFragTypeId();
        assertEquals(224, typeId[0]);
        assertEquals(225, typeId[1]);
        assertEquals(255, typeId[2]);

        //选择通道2
        selectSlot(2);
//        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,1);
        //给通道2设置浓度为lvl1
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_1);
//        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,1);
        delay(1000);
        int slot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        assertEquals(SLOT_2, slot);
        int lvl = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(LVL_1, lvl);
        delay(3000);

        //反馈的香氛浓度为fragLvlFrmClima=2(Lvl2)
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2, 2);
        delay(4000);
        //检查CSD是否根据反馈信号同步香氛通道和香氛浓度等级
        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(LVL_2, res);
    }

    @Test
    public void test_007setSlot2Lvl2(){
        setCarConfig(false);
        setCarConfig(true);
        setCem(false);
        setCem(true);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0, 2, 0);
        selectSlot(2);

        delay();
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,2);
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_2);
        delay(4000);

        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(),AREA_ID);
        int ch = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(),AREA_ID);
        assertEquals(LVL_2, res);
        assertEquals(SLOT_2, ch);
    }

    @Test
    public void test_008UsgModFrmInActvToCnvincStsOnNoReq(){
        setCarConfig(false);
        setCarConfig(true);
        mockTypeIdFrmMcu(224,225,255);
        //选择通道2
        selectSlot(2);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,0, 0);
        assertEquals(SLOT_2, mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID));
        //UsgMode从Inactive变为Convenience,sts=on,lvl=noReq
        setUsgModInactive();
        delay(4000);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2, 0);
        delay(3000);
        //开启香氛，恢复上一次保存的浓度
        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(),AREA_ID);
        assertEquals(LVL_2,res);
    }

    @Test
    public void test_009UsgModFrmInActvToCnvincStsOff(){
//        setCarConfig(false);
        setCarConfig(true);
        setCem(true);
        mockTypeIdFrmMcu(224,225,255);
        //先选择通道2，设为浓度1
//        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,1);
        selectSlot(2);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,0,0);
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_1);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,1);
        delay();
        int ch = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        int lvl = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(SLOT_2, ch);
        assertEquals(LVL_1, lvl);
        delay(4000);

        //UsgMode变为Inactive,会记忆当前用户设置的香氛浓度等级
        setUsgModInactive();
        //此时香氛浓度切换至NotActive状态
        assertEquals(1, mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus());

        //恢复至active状态
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,1, 0);
        delay(4000);
        //检查通道是否为2
        int curch = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        assertEquals(SLOT_2,curch);
        //检查保存的浓度值是否为lvl2, typeId!=0,sts=off,此时选择通道后会恢复上次保存的浓度
        int lastSet = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(LVL_1, lastSet);
    }


    @Test
    public void test_010OnSetPropMcuLvlNoReq(){
        //case1 fragLvlFrmClima==0(NoRequest)香氛浓度等级没有请求时 && fragStsFrmClima==1(AirFragSts_OFF)香氛工作状态是关闭时
        setCarConfig(false);
        setCarConfig(true);
        setCem(true);
        selectSlot(1);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,1,0,0,1, 0);
        delay();
        //切换至通道2，上次记忆的浓度为1
        selectSlot(2);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,1, 0);
        delay();
        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        //同步切换至off
        assertEquals(LVL_OFF, res);
    }

    @Test
    public void test_011OnSetPropNormal(){
        //case2 用户选择浓度等级 && fragStsFrmClima==AirFragSts_ON(0x02)香氛工作状态是开启时
        setCarConfig(false);
        setCarConfig(true);
        setCem(true);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,0,1,2,0);
        selectSlot(3);
        delay();
        int[] settings = {LVL_OFF, LVL_1, LVL_2, LVL_3};
        int res = 0;
        //进行4个等级的浓度设置并检查
        for(int i = 0; i < settings.length; i++){
            mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, settings[i]);
            mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,0,1,2,i);
            delay();
            res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
            assertEquals(settings[i], res);
            delay(3000);
        }
    }

    @Test
    public void test_012OnSetPropMcuStsError(){
        //case3 FragStsFrmClima==AirFragSts_Error(0x03)香氛工作状态是错误时
        setCarConfig(true);
        setCem(true);
        selectSlot(1);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,1,0,0,3,0);
        //浓度等级置灰显示并且提醒用户香氛当前不可用
        delay();
        int propStatus = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(1, propStatus);
    }

    @Test
    public void test_013AirFragLevelCallBack(){
        CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {
                cbkPropValue = (int)carPropertyValue.getValue();
                cbkPropStatus = carPropertyValue.getStatus();
            }

            @Override
            public void onErrorEvent(int i, int i1) {

            }
        };

        mCarPropertyMgr.registerCallback(carPropertyEventCallback, propertyId.getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE);
        CarPropertyValue<Integer> carProp = mCarPropertyMgr.getProperty(Integer.class, propertyId.getPropertyId(), AREA_ID);
        int oldPropStatus = carProp.getStatus();
        if(oldPropStatus == 0){
            //set notAvail
            setCarConfig(false);
            delay();
            assertEquals(false, availability());
        }else{
            //set Active
            setCarConfig(false);
            setCarConfig(true);
            setCem(true);
            mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,0);
            assertEquals(0, cbkPropStatus);
            selectSlot(2);
            mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,225,255,0,1,0,2,2);
            delay(3000);
            assertEquals(LVL_2, cbkPropValue);
        }
        mCarPropertyMgr.unregisterCallback(carPropertyEventCallback);
    }

    @Test
    public void test_004McuOff(){
        setCarConfig(false);
        setCarConfig(true);
        setCem(false);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(225, 0,0,1, 0, 0, 2, 0);
        selectSlot(1);
        delay(3000);
        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        int slot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        assertEquals(LVL_OFF, res);
        assertEquals(SLOT_1, slot);
    }
    
    @Test
    public void test_014SettingChangewithoutMcu(){
        setCarConfig(false);
        setCarConfig(true);
        setCem(false);
        setCem(true);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,0,0,1,0,0, 2, 0);
        selectSlot(1);

        delay();
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(224,0,0,1,0,0,2,1);
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_1);
        delay(4000);
        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(),AREA_ID);
        int ch = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(),AREA_ID);
        assertEquals(LVL_1, res);
        assertEquals(SLOT_1, ch);

        //只更改上层设置
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_2);
        res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(),AREA_ID);
        ch = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(),AREA_ID);
        assertEquals(LVL_2, res);
        assertEquals(SLOT_1, ch);
        //3秒后需要跳转到LVL1
        delay(4000);
        res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(),AREA_ID);
        ch = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(),AREA_ID);
        assertEquals(LVL_1, res);
        assertEquals(SLOT_1, ch);
    }

    @Test
    public void test_015SlotChange(){
        setCarConfig(false);
        setCarConfig(true);
        setCem(false);
        setCem(true);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(226, 0, 0, 1, 0, 0, 2, 1);
        selectSlot(1);
        delay();
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_1);
        delay(3000);
        int res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        int slot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        assertEquals(SLOT_1, slot);
        assertEquals(LVL_1, res);

        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(0, 226, 0, 0, 1, 0, 2, 2);
        selectSlot(2);
        delay();
        mCarPropertyMgr.setIntProperty(propertyId.getPropertyId(), AREA_ID, LVL_2);
        delay(3000);
        res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        slot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        assertEquals(SLOT_2, slot);
        assertEquals(LVL_2, res);

        delay();
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(226, 0, 0, 1, 0, 0, 2, 2);
        selectSlot(1);
        delay();
        res = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        slot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        assertEquals(SLOT_1, slot);
        assertEquals(LVL_1, res);
    }

    @Test
    public void test_016checkId(){
        setCarConfig(false);
        setCarConfig(true);
        setCem(true);
        //typeId和slot错位
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(0,0,225,1,0,0,0,0);
        delay(4000);
        int slot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        int lvlSts = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        int lvlVal = mCarPropertyMgr.getIntProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(SLOT_1, slot);
        //可用性变为NotActive
        assertEquals(1, lvlSts);
        //通知上层此时浓度变为0
        assertEquals(LVL_OFF, lvlVal);
    }

    @Test
    public void test_017checkIdChange(){
        setCarConfig(false);
        setCarConfig(true);
        setCem(true);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(0, 225, 0,1,0,0,0,0);
        int sts = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(1, sts);
        delay(3000);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(225, 0, 0, 1,0,0,0,0);
        sts = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(0, sts);
    }

    @Test
    public void test_018checkSlotChange(){
        setCarConfig(false);
        setCarConfig(true);
        setCem(true);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(0, 225, 0,1,0,0,0,0);
        int sts = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(1, sts);
        delay(3000);
        mockTypeIdAndAirFragChRunningStsAndStsAndLvl(0, 225, 0, 0,1,0,0,0);
        sts = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(0, sts);
    }
}